use super::*;

/// Serialization wrapper for N-API objects
pub struct Serialize {
	env: sys::napi_env,
	data: *mut core::ffi::c_void,
}
impl Drop for Serialize {
	fn drop(&mut self) {
		match unsafe { sys::napi_delete_serialization_data(self.env, self.data) }.result("napi_delete_serialization_data") {
			Ok(_) => {}
			Err(e) => {
				log::error!("napi_delete_serialization_data failed: {:?}", e);
			}
		}
	}
}
impl<'val> FromNapi<'val> for Serialize {
	/// Serializes a JavaScript value for later deserialization
	fn from_napi(value: Value<'val>) -> Result<'static, Self> {
		let mut data = core::ptr::null_mut();
		unsafe {
			sys::napi_serialize(
				value.env.raw(),
				value.inner,
				core::ptr::null_mut(),
				core::ptr::null_mut(),
				&mut data,
			)
		}
		.result("napi_serialize")?;
		Ok(Serialize { env: value.env.raw(), data })
	}
}
impl IntoNapi for Serialize {
	/// Deserializes a previously serialized value
	fn into_napi<'env>(self, env: &'env Env) -> Result<'static, Value<'env>> {
		let mut ret = core::ptr::null_mut();
		(unsafe { sys::napi_deserialize(self.env, self.data, &mut ret).result("napi_deserialize") })?;
		Ok(Value::new(env, ret))
	}
}